package com.hqyj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hqyj.dao.ExamQuestionInfoMapper;
import com.hqyj.dao.ExampaperMapper;
import com.hqyj.dao.QuestionMapper;
import com.hqyj.dao.ScoreManagementMapper;
import com.hqyj.pojo.ExamQuestionInfo;
import com.hqyj.pojo.Exampaper;
import com.hqyj.pojo.Question;
import com.hqyj.pojo.ScoreManagement;
import com.hqyj.service.ExampaperService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 试卷表 服务实现类
 * </p>
 *
 * @author rock
 * @since 2021-11-12
 */
@Service
public class ExampaperServiceImpl implements ExampaperService {
    /**
     * 注入 ExampaperMapper
     */
    @Autowired
    private ExampaperMapper exampaperMapper;

    /**
     * 注入 ExamQuestionInfoMapper
     */
    @Autowired
    private ExamQuestionInfoMapper examQuestionInfoMapper;

    /**
     * 注入 QuestionMapper
     */
    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 注入Redis工具类
     */
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 注入 ScoreManagementMapper
     */
    @Autowired
    private ScoreManagementMapper scoreManagementMapper;


    @Override
    public HashMap<String, Object> select(Exampaper exampaper) {
        HashMap<String, Object> map = new HashMap<>();
        // 分页对象
        Page<Exampaper> exampaperPage = new Page<>(exampaper.getPage(), exampaper.getRow());
        //System.err.println("Exampaper"+exampaper);
        // 条件构造器
        QueryWrapper<Exampaper> exampaperQueryWrapper = new QueryWrapper<>();
        // 条件查询
        exampaperQueryWrapper.eq(exampaper.getExamId() != null, "exam_id", exampaper.getExamId());
        exampaperQueryWrapper.like(
                (!StringUtils.isEmpty(exampaper.getExamTitle())) && exampaper.getExamTitle() != null,
                "exam_title", exampaper.getExamTitle());

        // 定义当前页的 key
        String curKey = "examPaper:list:" + exampaper.getPage() + ":" + exampaper.getRow() + ":" + exampaper.getExamId() + ":" + exampaper.getExamTitle() + ":";
        // 总条数
        String totalKey = "examPaper:total:" + exampaper.getPage() + ":" + exampaper.getRow() + ":" + exampaper.getExamId() + ":" + exampaper.getExamTitle() + ":";

        // 判断当前页在 Redis 中所有是否有
        Object obj = redisTemplate.opsForValue().get(curKey);
        if (obj != null) {
            map.put("info", "success");
            map.put("list", redisTemplate.opsForValue().get(curKey));
            map.put("total", redisTemplate.opsForValue().get(totalKey));
        } else {
            // 获取分页结果集
            Page<Exampaper> page = exampaperMapper.selectPage(exampaperPage, exampaperQueryWrapper);

            // 获取返回的分页结果集对象
            map.put("info", "success");
            map.put("list", page.getRecords());
            map.put("total", page.getTotal());

            // 添加数据到 Redis 缓存中
            redisTemplate.opsForValue().set(curKey, page.getRecords(), 30, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(totalKey, page.getTotal(), 30, TimeUnit.SECONDS);
        }

        return map;
    }

    @Override
    public HashMap<String, Object> generatePaper(Exampaper exampaper) {
        HashMap<String, Object> map = new HashMap<>();
        List<Question> questionList = exampaper.getExamList();
        if (questionList.size() > 10) {
            map.put("info", "所选试题总分大于100分");
        } else if (questionList.size() != 10) {
            map.put("info", "试题总分不足100分");
        } else {
            exampaper.setExamCreatetime(new Date());
            exampaper.setExamTitle(exampaper.getExamTitle() + System.currentTimeMillis());
            int insert = exampaperMapper.insert(exampaper);
            // 获取最大自增ID
            exampaper.setExamId(exampaperMapper.getLastInsertId());
            ExamQuestionInfo examQuestionInfo = new ExamQuestionInfo();
            //// 添加该试卷的试题信息
            for (Question question : questionList) {
                //System.err.println(exampaper.getExamId());
                examQuestionInfo.setExamId(exampaper.getExamId());
                examQuestionInfo.setQuestionId(question.getQuestionId());
                int num = examQuestionInfoMapper.insert(examQuestionInfo);
            }
            if (insert > 0) {
                map.put("info", "新增成功");
            } else {
                map.put("info", "新增失败");
            }
        }

        return map;
    }

    @Override
    public HashMap<String, Object> randGeneratePaper(Exampaper exampaper) {
        HashMap<String, Object> map = new HashMap<>();

        // 设置试卷生成时间
        exampaper.setExamCreatetime(new Date());
        // 设置试卷名称
        exampaper.setExamTitle(exampaper.getExamTitle() + System.currentTimeMillis());
        // 生成试卷
        int insert = exampaperMapper.insert(exampaper);
        //System.err.println("ExamPaper"+exampaper);

        //  获取最大自增ID
        exampaper.setExamId(exampaperMapper.getLastInsertId());

        // 单选题列表
        List<Question> questionListRadio = questionMapper.selectList(
                new QueryWrapper<Question>().like(true, "question_type", "单选题"));
        // 判断题列表
        List<Question> questionListBoolean = questionMapper.selectList(
                new QueryWrapper<Question>().like(true, "question_type", "判断题"));

        Random random = new Random();
        //random.nextInt(questionList.size()+1);
        // 单选题个数
        Integer radioNumber = exampaper.getRadioNumber();
        // 所有单选题 题数
        int questionListRadioSize = questionListRadio.size();
        // 添加当前试卷的单选题
        ExamQuestionInfo examQuestionInfo = new ExamQuestionInfo();
        // 设置试卷编号
        examQuestionInfo.setExamId(exampaper.getExamId());
        int radio = 0;
        for (int i = 0; i < radioNumber; i++) {
            // 设置题目ID
            examQuestionInfo.setQuestionId(questionListRadio.get(random.nextInt(questionListRadioSize)).getQuestionId());
            radio += examQuestionInfoMapper.insert(examQuestionInfo);
        }

        // 判断题个数
        Integer booleanNumber = exampaper.getBooleanNumber();
        // 所有判断题 题数
        int questionListBooleanSize = questionListBoolean.size();
        int boo = 0;
        for (int i = 0; i < booleanNumber; i++) {
            // 设置题目ID
            examQuestionInfo.setQuestionId(questionListBoolean.get(random.nextInt(questionListBooleanSize)).getQuestionId());
            boo += examQuestionInfoMapper.insert(examQuestionInfo);
        }

        if ((radioNumber == radio) && (booleanNumber == boo)) {
            map.put("info", "success");
        } else {
            map.put("info", "error");
        }
        return map;
    }

    @Override
    public HashMap<String, Object> previewPaper(Exampaper exampaper) {
        HashMap<String, Object> map = new HashMap<>();

        // 定义当前 预览试卷的 key
        String previewKey = "preview:list:" + exampaper.getExamId() + ":";

        Object obj = redisTemplate.opsForValue().get(previewKey);
        // 判断当前预览试卷信息是否在 Redis 缓存中
        if (obj != null) {
            map.put("list", redisTemplate.opsForValue().get(previewKey));
        } else {
            // 不在缓存中 去数据库查询
            List<Question> allQuestions = questionMapper.getAllQuestions(exampaper.getExamId());
            map.put("list", allQuestions);
            // 存入Redis 中
            redisTemplate.opsForValue().set(previewKey, allQuestions, 60, TimeUnit.SECONDS);
        }
        return map;
    }

    @Override
    public HashMap<String, Object> deletePaper(Integer examId) {
        HashMap<String, Object> map = new HashMap<>();
        // 删除试卷表中的信息
        int num = exampaperMapper.deleteById(examId);
        // 删除试卷题目表中的信息
        int result = examQuestionInfoMapper.deleteExamQuestionInfoByExamId(examId);
        if (num > 0 && result > 0) {
            map.put("info", "success");
        } else {
            map.put("info", "error");
        }
        return map;
    }

    @Override
    public HashMap<String, Object> examination(Exampaper exampaper, Integer stuId) {
        HashMap<String, Object> map = new HashMap<>();
        System.err.println("考试编号==" + exampaper.getExamId() + "，考生编号===" + stuId);
        // 查询考生是否参加过本场考试
        List<ScoreManagement> scoreList = scoreManagementMapper.selectScoreManagementByExamIdAndStuId(exampaper.getExamId(), stuId);
        if (scoreList.size() == 0) {
            // 获取 当前试卷的考题信息
            List<Question> allQuestions = questionMapper.getAllQuestions(exampaper.getExamId());
            exampaper = exampaperMapper.selectById(exampaper.getExamId());
            if (allQuestions.size() != 0) {
                map.put("info", "success");
                exampaper.setExamList(allQuestions);
                map.put("exam", exampaper);
            } else {
                map.put("info", "error");
            }
        } else {
            map.put("info", "already");
        }

        return map;
    }
}
